﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Business;
using System.Threading;
using System.Runtime.InteropServices;
using Settings;

namespace Sami_SMS_CRM
{
    class Program
    {
        #region declare variable
        static EventWaitHandle waitHandle;
        static EventWaitHandle timerHandle;
        static RegisteredWaitHandle registerTimer;
        static RegisteredWaitHandle registerHandle;
        static bool alreadyRegister;
        static bool IsRunning { get; set; }
        static bool flag { get; set; }
        static string readkey { get; set; }
        #endregion

        #region DllImport
        [DllImport("user32.dll")]
        public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);

        [DllImport("user32.dll")]
        private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

        [DllImport("kernel32.dll", ExactSpelling = true)]
        private static extern IntPtr GetConsoleWindow();
        #endregion

        static void Init()
        {
            new SQLNotifier().Start();
            waitHandle = new AutoResetEvent(false);
            timerHandle = new AutoResetEvent(false);
        }

        static void Main(string[] args)
        {
            try
            {
                //Disable close button
                DeleteMenu(GetSystemMenu(GetConsoleWindow(), false), 0xF060, 0x00000000);
                bool ownsMutex;
                string mutexName = "Local\\" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
                using (Mutex mutex = new Mutex(true, mutexName, out ownsMutex))
                {
                    if (ownsMutex)
                    {
                        Init();
                        ShowTitle();
                        do
                        {
                            readkey = Console.ReadLine();
                            switch (readkey)
                            {
                                case "1":
                                    Console.WriteLine("Starting...");
                                    flag = true;
                                    if (!alreadyRegister)
                                    {
                                        registerHandle = ThreadPool.RegisterWaitForSingleObject(waitHandle, Start, null, Timeout.Infinite, false);
                                        waitHandle.Set();
                                        registerTimer = ThreadPool.RegisterWaitForSingleObject(timerHandle, DeleteSubscriberClassificationExpired, null, LocalSettings.TimeExpired * 60 * 1000, false);
                                        alreadyRegister = true;
                                    }
                                    break;
                                case "2":
                                    Console.WriteLine("Pause...");
                                    flag = false;
                                    if (registerHandle != null)
                                    {
                                        registerHandle.Unregister(waitHandle);
                                    }
                                    if (registerTimer != null)
                                    {
                                        registerTimer.Unregister(timerHandle);
                                    }
                                    alreadyRegister = false;
                                    break;
                                case "3":
                                    Console.WriteLine("Thank you! Waiting for close program");
                                    flag = false;
                                    if (registerHandle != null)
                                    {
                                        registerHandle.Unregister(waitHandle);
                                    }
                                    if (registerTimer != null)
                                    {
                                        registerTimer.Unregister(timerHandle);
                                    }
                                    alreadyRegister = false;
                                    do
                                    {
                                        Thread.Sleep(Settings.Constants.Delaytime);
                                    } 
                                    while (IsRunning);
                                    return;
                                case "4":
                                    Console.Clear();
                                    ShowTitle();
                                    ShowStatus();
                                    break;
                                case "5":
                                    Console.Clear();
                                    LocalSettings.TurnOnSendMessage = !LocalSettings.TurnOnSendMessage;
                                    ShowTitle();
                                    ShowStatus();
                                    break;
                                default:
                                    Console.WriteLine("Key pressed is invalid! Please repress any key flowing instruction: \n" +
                                                    "  1: Start \n" +
                                                    "  2: Pause \n" +
                                                    "  3: Stop \n" +
                                                    "  4: Clear Screen \n");
                                    break;
                            }
                        }
                        while (true);
                    }
                }
            }
            catch (Exception e)
            {
                new LogRepository().InsertLog(e);
                Console.ReadLine();
            }
        }

        private static void ShowTitle()
        {
            Console.WriteLine(
                "======================================================\n" +
                "=                                                    =\n" +
                "=                Welcome to SMS CRM System           =\n" +
                "=                                                    =\n" +
                "======================================================\n\n" +
                "Allow send message: " + (LocalSettings.TurnOnSendMessage ? "TRUE" : "FALSE") + "\n\n" +
                "Press any key flowing instruction: \n" +
                "   1: Start \n" +
                "   2: Pause \n" +
                "   3: Stop \n" +
                "   4: Clear Screen \n" +
                "   5: Turn ON/OFF send Message"
            );
        }

        private static void ShowStatus()
        {
            if (flag)
            {
                Console.WriteLine("Starting...");
            }
            else
            {
                Console.WriteLine("Pause...");
            }
        }
       
        static void Start(object state, bool timedout)
        {
            if (timedout)
            {
                if (!IsRunning)
                    Start();
            }
            else
            {
                if (!IsRunning)
                {
                    Start();
                }
            }
        }

        static void Start()
        {
            try
            {
                DeleteSubscriberClassificationExpired(null, false);
                IsRunning = true;
                AdvertismentRepositiory adv = new AdvertismentRepositiory();
                while (flag)
                {
                    adv.AdvertismentExecute();
                    Thread.Sleep(1000);
                }
            }
            catch (Exception e)
            {
                new LogRepository().InsertLog(e);
            }
            finally
            {
                IsRunning = false;
            }
        }

        static void DeleteSubscriberClassificationExpired(object state, bool timedout)
        {
            try
            {
                new Subscriber_ClassificationRepository().DeleteRecordExpired();
            }
            catch (Exception ex)
            {
                new LogRepository().InsertLog(ex);
            }
        }
    }
}
